<template>
  <div class="app-container disf">
    <!-- 流程模板列表 -->
    <el-card shadow="hover" class="h mr10" style="width: 300px;overflow-y: auto;" header="流程模板" v-loading="flowLoading">
      <div class="flow-add-button" @click="handleEdit()">
        <p>+ 新增模板</p>
      </div>
      <div v-for="flow in flowList" :key="flow.id" class="temp-item" :class="{ active: curFlow?.id == flow.id }"
        @click="handleChange(flow)">
        <p>{{ flow.name }}</p>
        <span>{{ flow.remark }}</span>
      </div>
    </el-card>

    <!-- 流程明细 -->
    <el-card shadow="hover" header="流程明细" class="flex1 h" v-loading="nodeLoading">
      <template v-if="curFlow" #header>
        {{ `流程模板【${curFlow?.name}】` }}
        <el-button size="small" type="primary" icon="edit" @click="handleEdit(curFlow)">
          编辑流程
        </el-button>
        <el-button size="small" type="primary" icon="copy" @click="copyFlow(curFlow)">
          复制流程
        </el-button>
        <el-popconfirm title="确定删除流程？" confirm-button-text="确认" cancel-button-text="取消" @confirm="deleteFlow(curFlow)">
          <template #reference>
            <el-button size="small" type="primary" icon="delete">
              删除流程
            </el-button>
          </template>
        </el-popconfirm>
      </template>
      <el-scrollbar always v-if="curFlow">
        <div class="flow-node-wrap">
          <!-- 遍历：节点列表 -->
          <template v-for="(node, idx) in nodeList" :key="node.id">
            <div class="flow-node">
              <!-- 节点名称 -->
              <div class="node-name">
                <div class="node-index ml25">{{ idx + 1 }}</div>
                <div class="disf dirc flex1 w0 plr15">
                  <b>{{ node.name }}</b>
                  <span class="node-remark" :title="node.remark">
                    {{ node.remark || "暂无描述" }}
                  </span>
                </div>
                <el-tag type="primary" effect="plain" class="node-tag mr15">
                  {{ FLOW_NODE_TYPE_LABEL[node.nodeType] }}
                  <el-tooltip v-if="node.nodeType == FlowNodeType.AUDITOR_NODE" :content="getAuditBackName(node)"
                    placement="top">
                    <el-icon style="cursor: pointer">
                      <QuestionFilled />
                    </el-icon>
                  </el-tooltip>
                </el-tag>
              </div>
              <!-- 节点任务列表 -->
              <ol class="node-tasks">
                <li class="task-line" v-for="task in node.flowNodeTasks">
                  <div class="task-title">
                    <b>{{ task.name }}</b>
                    <span class="role-icon">
                      <el-icon class="mr5">
                        <User />
                      </el-icon>
                      {{ FLOW_ACT_ROLE_LABEL[task.activityRole] }}
                    </span>
                  </div>
                  <div class="task-remark" :title="task.remark">
                    <span>{{ task.remark }}</span>
                  </div>
                  <div class="task-remark disf alc">
                    <el-icon class="mr5">
                      <Postcard />
                    </el-icon>
                    {{ FLOW_CANDIDAT_TYPE_LABEL[task.candidateType] }}【{{ task.candidateName }}】
                  </div>
                  <div class="task-remark disf alc juend">
                    <el-button size="small" link icon="warning" type="primary" @click="handleDtlTask(task.id)">
                      详情
                    </el-button>
                    <el-button size="small" link icon="edit" type="primary" @click="handleEditTask(node, task.id)">
                      编辑
                    </el-button>
                    <el-button :disabled="task.systemd" size="small" link icon="delete" type="danger"
                      @click="handleDelTask(task)">
                      删除
                    </el-button>
                  </div>
                </li>
                <li class="flow-add-button" @click="handleEditTask(node)">+ 添加任务</li>
              </ol>
            </div>
          </template>
        </div>
      </el-scrollbar>
      <el-empty v-else description="暂无数据，请编辑流程添加节点"></el-empty>
    </el-card>
    <!-- 弹窗：编辑流程 -->
    <Edit :data="dialog.data" :visible="dialog.visible" @dialogClose="closeEdit"></Edit>
    <!-- 弹窗：编辑节点任务 -->
    <EditTask :id="dialogTask.id" :flowId="curFlow?.id" :nodeType="dialogTask.nodeType" :nodeId="dialogTask.nodeId"
      :visible="dialogTask.visible" @dialogClose="closeEditTask"></EditTask>
    <!-- 弹窗：查询节点任务 -->
    <TaskDetail :id="dialogTaskDtl.id" :visible="dialogTaskDtl.visible" @dialogClose="closeDtlTask"></TaskDetail>
  </div>
</template>

<script lang="ts" setup>
import FlowAPI, { FlowPageVO } from "@/api/flow/flow.api";
import FlowNodeAPI, {
  FLOW_AUDIT_TYPE_LABEL,
  FLOW_NODE_TYPE_LABEL,
  FlowAuditorType,
  FlowNodeType,
  FlowNodeVo,
} from "@/api/flow/flowNode.api";
import Edit from "./edit.vue";
import EditTask from "./taskEdit.vue";
import TaskDetail from "./taskDetail.vue";
import FlowNodeTaskAPI, {
  FLOW_ACT_ROLE_LABEL,
  FLOW_CANDIDAT_TYPE_LABEL,
  FlowNodeTaskVo,
} from "@/api/flow/flowNodeTask.api";
import { DeleteFilled } from "@element-plus/icons-vue/dist/types";

const flowList = ref<FlowPageVO[]>([]);
const curFlow = ref<FlowPageVO>(); //选中的模板
const nodeList = ref<FlowNodeVo[]>([]); //模板节点列表

const flowLoading = ref(false);
const nodeLoading = ref(false);

onMounted(() => {
  // 获取流程模板列表
  loadFlowList(() => {
    if (flowList.value.length) {
      handleChange(flowList.value[0]);
    }
  });
});

/**
 * 获取流程模板列表
 * @param id 选中的id
 */
async function loadFlowList(cb?: () => void) {
  flowLoading.value = true;
  const data = await FlowAPI.getPage({
    pageNum: 1,
    pageSize: 999,
  });
  flowList.value = data.list;
  flowLoading.value = false;
  cb && cb();
}

/**
 * 切换选中的模板
 */
function handleChange(flow?: FlowPageVO) {
  curFlow.value = flow;
  loadFlowDetail();
}

// 加载详情
const loadFlowDetail = () => {
  if (!curFlow.value) {
    nodeList.value = [];
    return;
  }
  nodeLoading.value = true;
  // 加载节点列表
  FlowNodeAPI.getNodes(curFlow.value.id)
    .then((data) => {
      nodeList.value = data;
    })
    .finally(() => {
      nodeLoading.value = false;
    });
};

// 获取审核回退的节点
function getAuditBackName(node: FlowNodeVo) {
  const backNode = nodeList.value.find((item) => item.id == node.backNodeId);
  return `审核方式：${FLOW_AUDIT_TYPE_LABEL[node.auditorType!]}，审核不通过回退至：${backNode?.name}`;
}

/**
 * 新增/编辑弹窗
 */
const dialog = reactive<{
  visible: boolean;
  data?: FlowPageVO;
}>({
  visible: false,
});

function handleEdit(data?: FlowPageVO) {
  dialog.visible = true;
  dialog.data = data;
}
// 删除流程
function deleteFlow(data: FlowPageVO) {
  FlowAPI.deleteById(data.id).then(() => {
    loadFlowList(() => {
      if (flowList.value.length) {
        handleChange(flowList.value[0]);
      }
    });
  });
}

// 复制流程
function copyFlow(data: FlowPageVO) {
  FlowAPI.copy(data.id).then(() => {
    loadFlowList();
  });
}

// 关闭弹窗
function closeEdit(id?: string) {
  dialog.visible = false;
  // 刷新列表，选中新模板
  if (id) {
    loadFlowList(() => {
      const nFlow = flowList.value.find((item) => item.id == id);
      handleChange(nFlow!);
    });
  }
}

/**
 * 新增/编辑 任务弹窗
 */
const dialogTask = reactive<{
  visible: boolean;
  nodeId: string;
  id?: string;
  nodeType?: string;
}>({
  visible: false,
  nodeId: "",
});

function handleEditTask(node: FlowNodeVo, id?: string) {
  dialogTask.visible = true;
  dialogTask.id = id;
  dialogTask.nodeId = node.id!;
  dialogTask.nodeType = node.nodeType;
}

// 关闭任务弹窗
function closeEditTask(isRefresh?: boolean) {
  dialogTask.visible = false;
  if (isRefresh) {
    loadFlowDetail();
  }
}

/**
 * 任务详情弹窗
 */
const dialogTaskDtl = reactive<{
  visible: boolean;
  id?: string;
}>({
  visible: false,
});

function handleDtlTask(id?: string) {
  dialogTaskDtl.visible = true;
  dialogTaskDtl.id = id;
}

function closeDtlTask() {
  dialogTaskDtl.visible = false;
}

/**
 * 删除任务
 */
function handleDelTask(task?: FlowNodeTaskVo) {
  if (!task) return;
  ElMessageBox.confirm(`确认删除任务【${task.name}】?`, "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(() => {
    FlowNodeTaskAPI.deleteById(task.id!).then(() => {
      ElMessage.success("删除成功");
      loadFlowDetail();
    });
  });
}
</script>

<style lang="scss" scoped>
:deep(.el-card__body) {
  height: calc(100% - 70px);
}

.temp-item {
  border: 1px solid #eee;
  border-radius: 5px;
  padding: 10px 14px;
  margin-bottom: 10px;
  cursor: pointer;
  transition: all 0.3s ease-in-out;

  p {
    padding-bottom: 3px;
  }

  span {
    font-size: 0.75em;
    color: #999;
  }

  &:hover {
    border-color: #ccc;
    box-shadow: 3px 3px 5px #ccc;
  }

  &.active {
    border-color: var(--el-color-primary);

    p {
      color: var(--el-color-primary);
      font-weight: bold;
    }

    span {
      color: #666;
    }
  }
}

.flow-node-wrap {
  display: flex;
  white-space: nowrap;
}

.flow-node {
  display: flex;
  width: 18em;
  flex-shrink: 0;
  margin-right: 16px;
  margin-bottom: 15px;
  flex-direction: column;
  font-size: 0.9em;

  .node-name {
    display: flex;
    align-items: center;
    padding: 5px 10px;
    margin-right: -20px;
    // background-color: var(--el-bg-color-page);
    background: url("data:image/svg+xml;charset=utf-8,%3Csvg t='1755228742853' class='icon' viewBox='0 0 1702 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='15610' data-spm-anchor-id='a313x.search_index.0.i8.6e8f3a81r1hw4J' width='60' height='60'%3E%3Cpath d='M1701.385 541.177l-230.083-234.545H0l216.77 233.967L0 776.004h1471.302z' p-id='15611' data-spm-anchor-id='a313x.search_index.0.i7.6e8f3a81r1hw4J' class='' fill='%23d9e6ff'%3E%3C/path%3E%3C/svg%3E") no-repeat right 52% / 105% auto;
    margin-bottom: 7px;

    .node-index {
      font-size: 1.6em;
      font-weight: bold;
      color: #fff;
      text-shadow: 1px 1px 4px #999;
    }

    .node-remark {
      font-size: 0.75em;
      color: #aaa;
      white-space: nowrap;
      /* 防止文本换行 */
      overflow: hidden;
      /* 隐藏超出部分的文本 */
      text-overflow: ellipsis;
      /* 显示省略号 */
    }

    .node-tag {
      background: none;
    }
  }

  .node-tasks {
    flex: 1;
    padding: 12px 7px 5px;
    background-color: #f3f4fb;
    border-radius: 7px;

    .task-line {
      padding: 5px 10px;
      background-color: #fff;
      border-radius: 9px;
      margin-bottom: 9px;

      .task-title {
        display: flex;
        justify-content: space-between;
        align-items: center;

        .role-icon {
          display: flex;
          align-items: center;
          color: #999;
          font-size: 0.8em;
        }
      }

      .task-remark {
        font-size: 0.75em;
        margin-top: 5px;
        white-space: nowrap;
        /* 防止文本换行 */
        overflow: hidden;
        /* 隐藏超出部分的文本 */
        text-overflow: ellipsis;
        /* 显示省略号 */
      }
    }
  }
}

/* 添加按钮 */
.flow-add-button {
  border: 1px dashed #d1d1d1;
  border-radius: 5px;
  padding: 15px;
  background-color: #fff;
  border-radius: 9px;
  margin-bottom: 9px;
  font-weight: bold;
  cursor: pointer;
  color: #9e9e9e;
  transition: all 0.3s ease-in-out;

  &:hover {
    border-color: var(--el-color-primary);
    color: var(--el-color-primary);
  }
}
</style>
